package com.yonyou.pmclouds.stagecheck.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.entity.SuperVO;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemBillStatusConst;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemVO;
import com.yonyou.pmclouds.inspectitem.mapper.InspectItemMapper;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.plan.entity.ScheduleItemVO;
import com.yonyou.pmclouds.plan.mapper.ScheduleItemMapper;
import com.yonyou.pmclouds.pmpub.entity.QueryListParam;
import com.yonyou.pmclouds.pmpub.rmiitf.IPageQuerySerivce;
import com.yonyou.pmclouds.project.entity.ProjectRefVO;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.mapper.ProjectMapper;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.stagecheck.entity.StageCheckVO;
import com.yonyou.pmclouds.stagecheck.mapper.StageCheckMapper;
import com.yonyou.pmclouds.stagecheck.rmitf.StageCheckQuery;
import com.yonyou.pmclouds.workquality.entity.WorkqualityDetailVO;
import com.yonyou.pmclouds.workquality.entity.WorkqualityVO;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityDetailMapper;
import com.yonyou.pmclouds.workquality.mapper.WorkqualityMapper;
import com.yonyou.pmclouds.workquality.service.rmiitf.WorkqualityQueryService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @Author chulf
 * @Date 2020/3/31
 * @Description
 **/
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = StageCheckQuery.class)
public class StageCheckQueryImpl implements StageCheckQuery, IPageQuerySerivce {
    @Autowired
    private StageCheckMapper mapper;
    @Autowired
    private WorkqualityMapper workqualityMapper;
    @Autowired
    private WorkqualityDetailMapper workqualityDetailMapper;
    @Autowired
    private InspectItemMapper inspectItemMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private WorkqualityQueryService qualityQuery;
    @Autowired
    private ScheduleItemMapper scheduleItemMapper;
    @Autowired
    private PictureRemoteService picService;
    @Autowired
    private ProjectSimpleQuery projectSimpleQuery;


    @Override
    public StageCheckVO[] queryByProject(String pkProject) throws BusinessException {

        StageCheckVO[] stageCheckVOS = mapper.selectStageCheckVOByPkProject(pkProject);

        //填充检查标准名称
        fillInspectstandardName(stageCheckVOS);

        //填充任务
        fillPlan(stageCheckVOS);

        return stageCheckVOS;
    }

    @Override
    public StageCheckVO queryOneByPk(String pkStageCheck) throws BusinessException {

        StageCheckVO stageCheckVO = mapper.getById(pkStageCheck);

        //填充检查标准
        fillWorkquality(stageCheckVO);

        //填充项目信息
        fillProjectInfo(stageCheckVO);

        //填充检查项内容(名字及描述)
        fillInspectItem(stageCheckVO);

        //填充任务
        fillPlan(new StageCheckVO[]{stageCheckVO});

        return stageCheckVO;
    }

    @Override
    public StageCheckVO[] queryByPks(Set<String> pks) throws BusinessException {

        StageCheckVO[] stageCheckVOS = mapper.selectStageCheckVOSByPks(pks);

        fillInspectstandardName(stageCheckVOS);
        fillPlan(stageCheckVOS);

        return stageCheckVOS;
    }

    @Override
    public PageObject<Object> queryByCondition(String[] pkProjects, String[] creators, String startDate, String endDate, int[] billStatus, int pageStart, int pageSize) throws BusinessException {

        int count = mapper.countByCondition(pkProjects, creators, startDate, endDate, billStatus);
        StageCheckVO[] stageCheckVOS = mapper.queryByCondition(pkProjects, creators, startDate, endDate, billStatus, pageStart, pageSize);

        //填充计划
        fillPlan(stageCheckVOS);
        //填充验收项名称
        fillInspectstandardName(stageCheckVOS);
        //填充合格数，验收数
        fillCheckCount(stageCheckVOS);

        return new PageObject<Object>(stageCheckVOS,count,pageStart);
    }

    /**
     *  填充检查标准名称
     * @param stageCheckVOS
     * @throws BusinessException
     */
    private void fillInspectstandardName(StageCheckVO[] stageCheckVOS) throws BusinessException {
        Set<String> pkInspectstandardSet = new HashSet<String>();
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            pkInspectstandardSet.add(stageCheckVO.getPkWorkquality());
        }
        Map<String, WorkqualityVO> workqualityVOMap = qualityQuery
                .queryByIDs(pkInspectstandardSet.toArray(new String[pkInspectstandardSet.size()]));

        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            WorkqualityVO workqualityVO = workqualityVOMap.get(stageCheckVO.getPkWorkquality());
            if (workqualityVO != null) {
                stageCheckVO.setInspectstandardName(workqualityVO.getCheckname());
            }
        }
    }

    /**
     *  填充检查标准
     * @param stageCheckVO
     */
    private void fillWorkquality(StageCheckVO stageCheckVO){

        WorkqualityVO workquality = workqualityMapper.getById(stageCheckVO.getPkWorkquality());
        stageCheckVO.setWorkqualityVO(workquality);
        stageCheckVO.setInspectstandardName(workquality.getCheckname());
    }

    /**
     *  填充项目信息
     * @param stageCheckVO
     * @throws BusinessException
     */
    private void fillProjectInfo(StageCheckVO stageCheckVO) throws BusinessException {

        ProjectVO projectVO = projectMapper.getById(stageCheckVO.getPkProject());
        stageCheckVO.setProjectVO(projectVO);

        if(StringUtils.isNotEmpty(projectVO.getPkOrg())) {
            OrganizationVO[] organizationVOs = organizationQuery.queryByPkSrcs(RuntimeEnvironment.getTenantId(), new String[]{projectVO.getPkOrg()});
            stageCheckVO.setOrgName(organizationVOs[0].getSname());

        }
    }

    /**
     *  填充检查项
     * @param stageCheckVO
     * @throws BusinessException
     */
    private void fillInspectItem(StageCheckVO stageCheckVO) throws BusinessException {
        InspectItemVO[] inspectItemVOS = inspectItemMapper.selectByBill(stageCheckVO.getPkStageCheck());
        if (ArrayUtils.isEmpty(inspectItemVOS)) return;

        HashMap<String, InspectItemVO> inspectItemVOMap = new HashMap<>();

        for (InspectItemVO inspectItemVO : inspectItemVOS) {
            inspectItemVOMap.put(inspectItemVO.getPk_item(),inspectItemVO);
        }

        WorkqualityDetailVO[] workqualityDetailVOS = workqualityDetailMapper.queryByPks(inspectItemVOMap.keySet().toArray(new String[0]));
        for (WorkqualityDetailVO workqualityDetailVO : workqualityDetailVOS) {
            InspectItemVO inspectItemVO = inspectItemVOMap.get(workqualityDetailVO.getPkWorkqualitydetail());
            inspectItemVO.setItem_name(workqualityDetailVO.getCheckitem());
            inspectItemVO.setItem_content(workqualityDetailVO.getCheckdescription());
        }
        stageCheckVO.setInspectItemVOS(inspectItemVOS);
    }

    /**
     * 填充计划
     * @param stageCheckVOS
     * @throws BusinessException
     */
    private void fillPlan(StageCheckVO[] stageCheckVOS) throws BusinessException{

        // 计划主键
        HashSet<String> pks = new HashSet<>();
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            pks.add(stageCheckVO.getPkScheduleItem());
        }

        if(pks.isEmpty()) return;

        HashMap<String, ScheduleItemVO> pk2ScheduleItem = new HashMap<>();
        List<ScheduleItemVO> scheduleItemVOS = scheduleItemMapper.queryByPkItems(pks.toArray(new String[0]));
        for (ScheduleItemVO scheduleItemVO : scheduleItemVOS) {
            pk2ScheduleItem.put(scheduleItemVO.getPkScheduleItem(),scheduleItemVO);
        }
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            stageCheckVO.setScheduleItemVO(pk2ScheduleItem.get(stageCheckVO.getPkScheduleItem()));
        }
    }


    /**
     *  统计合格数，验收总数
     * @param stageCheckVOS
     * @throws BusinessException
     */
    private void fillCheckCount(StageCheckVO[] stageCheckVOS) throws BusinessException{
        HashSet<String> pks = new HashSet<>();
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            pks.add(stageCheckVO.getPkStageCheck());
        }

        InspectItemVO[] inspectItemVOS = inspectItemMapper.queryByPkBills(pks.toArray(new String[0]));

        //根据stageCheck 做归类
        HashMap<String, List<InspectItemVO>> pk2InspectItem = new HashMap<>();
        for (InspectItemVO inspectItemVO : inspectItemVOS) {
            List<InspectItemVO> inspectItems = pk2InspectItem.get(inspectItemVO.getPk_bill());

            if (inspectItems == null) inspectItems = new ArrayList<InspectItemVO>();

            inspectItems.add(inspectItemVO);
        }

        //统计合格项，验收项总数
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            List<InspectItemVO> tempData = pk2InspectItem.get(stageCheckVO.getPkStageCheck());

            if (tempData == null || tempData.isEmpty()) {
                stageCheckVO.setQualifiedItem(0);
                stageCheckVO.setCheckItem(0);
            } else {

                int passCount = 0; //合格数
                for (InspectItemVO inspectItemVO : tempData) {

                    if (inspectItemVO.getBillstatus() == InspectItemBillStatusConst.BILLSTATUS_PASS) {
                        passCount+=1;
                    }
                }
                stageCheckVO.setQualifiedItem(passCount);
                stageCheckVO.setCheckItem(tempData.size());
            }
        }
    }

    /**
     *  填充图片 最多九张
     * @param vos
     * @throws BusinessException
     */
    private void fillPictures(StageCheckVO[] vos) throws BusinessException {
        Set<String> pkBills = new HashSet<>();
        for (StageCheckVO vo : vos) {
            if (vo != null && vo.getPkStageCheck() != null) pkBills.add(vo.getPkStageCheck());
        }
        if (pkBills.size() == 0) return;

        InspectItemVO[] inspectItemVOS = inspectItemMapper.queryByBillPks(SqlUtil.getSqlIn(pkBills.toArray(new String[0])));
        Map<String, String> recordParent = new HashMap<>();
        if (ArrayUtils.isEmpty(inspectItemVOS)) return;

        pkBills.clear();  //清空集合
        for (InspectItemVO vo : inspectItemVOS) {  //取不合格的检查项
            if (vo != null && vo.getBillstatus() == InspectItemBillStatusConst.BILLSTATUS_NO_PASS && vo.getPk_inspectitem() != null) {
                pkBills.add(vo.getPk_inspectitem());  //存入检查项主键
                recordParent.put(vo.getPk_inspectitem(), vo.getPk_bill());
            }
        }
        if (pkBills.size() == 0) return;

        Map<String, List<String>> picMap = picService.queryPicsByPkEntitys(pkBills.toArray(new String[0]));
        if (picMap == null) return;
        Map<String, List<String>> parentPicMap = new HashMap<>();

        for (String key : picMap.keySet()) {
            String pkParent = recordParent.get(key); //检查项主键对应的单据(施工记录)主键
            if (pkParent != null) {   //key是检查项主键
                if (parentPicMap.get(pkParent) == null) {
                    parentPicMap.put(pkParent, new ArrayList<String>());
                }
                if (parentPicMap.get(pkParent).size() < 9) {  //最多取9张照片
                    int need = 9 - parentPicMap.get(pkParent).size();
                    for (int i = 0; i < Math.min(need, picMap.get(key).size()); i++) {
                        parentPicMap.get(pkParent).add(picMap.get(key).get(i));
                    }
                }
            }
        }
        for (StageCheckVO vo : vos) {
            if (vo != null && parentPicMap.get(vo.getPkStageCheck()) != null) {
                vo.setPictures(parentPicMap.get(vo.getPkStageCheck()).toArray(new String[0]));
            }
        }
    }

    /**
     * 填充项目信息
     * @param stageCheckVOS
     * @throws BusinessException
     */
    private void fillProjectInfo(StageCheckVO[] stageCheckVOS) throws BusinessException {
        if (ArrayUtils.isEmpty(stageCheckVOS)) {
            return;
        }
        Set<String> pkProjectSet = new HashSet<String>();

        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            pkProjectSet.add(stageCheckVO.getPkProject());
        }


        Set<String> pkSrcOrgSet = new HashSet<>();
        Map<String, ProjectRefVO> projectRefVOMap = projectSimpleQuery.queryRefs(pkProjectSet.toArray(new String[pkProjectSet.size()]));
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            stageCheckVO.setProjectCode(projectRefVOMap.get(stageCheckVO.getPkProject()).getScode());
            stageCheckVO.setProjectName(projectRefVOMap.get(stageCheckVO.getPkProject()).getSname());
            stageCheckVO.setManager(projectRefVOMap.get(stageCheckVO.getPkProject()).getManager());
            if (StringUtils.isNotEmpty(projectRefVOMap.get(stageCheckVO.getPkProject()).getPkOrg()))
                pkSrcOrgSet.add(projectRefVOMap.get(stageCheckVO.getPkProject()).getPkOrg());
        }

        OrganizationVO[] organizationVOs = organizationQuery.queryByPkSrcs(RuntimeEnvironment.getTenantId(), pkSrcOrgSet.toArray(new String[0]));

        Map<String, OrganizationVO> orgMap = new HashMap<>();

        for (OrganizationVO orgVO : organizationVOs) {
            orgMap.put(orgVO.getPkSrc(), orgVO);
        }
        String pkTemp = "";
        for (StageCheckVO stageCheckVO : stageCheckVOS) {
            pkTemp = projectRefVOMap.get(stageCheckVO.getPkProject()).getPkOrg();
            if (orgMap.get(pkTemp) != null) {
                stageCheckVO.setOrgName(orgMap.get(pkTemp).getSname());
            }
        }

    }

    @Override
    public SuperVO[] queryByProject(QueryListParam param) throws BusinessException {

        StageCheckVO[] stageCheckVOS = mapper.queryByCondition(new String[]{param.getPkProject()}, null,
                param.getStartDate(), param.getEndDate(), null, param.getPageStart(), param.getPageSize());

        //填充检查标准
        fillInspectstandardName(stageCheckVOS);

        //填充项目信息
        fillProjectInfo(stageCheckVOS);

        //填充任务项
        fillPlan(stageCheckVOS);

        //填充图片
        fillPictures(stageCheckVOS);

        return stageCheckVOS;
    }

    @Override
    public int countByProject(QueryListParam param) throws BusinessException {
       return mapper.countByCondition(new String[]{param.getPkProject()}, null,
                param.getStartDate(), param.getEndDate(), null);
    }

    @Override
    public String getBillType() {
        return BillTypeConst.STAGECHECK_BILLTYPE;
    }
}
